home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 7 / BBS in a Box - Macintosh - Volume VII (BBS in a Box) (January 1993).iso / Files / Prog / T / TIFF Code.cpt / tiffio.c < prev    next >
Text File  |  1987-12-16  |  18KB  |  670 lines

  1. /* Standard C Include files */
  2. /* #include "CType.h" */
  3. /* #include "ErrNo.h" */
  4. /* #include "FCntl.h" */
  5. /* #include "IOCtl.h" */
  6. /* #include "Math.h" */
  7. /* #include "SetJmp.h" */
  8. /* #include "Signal.h" */
  9. /* #include "StdIO.h" */
  10. /* #include "String.h" */
  11.  
  12. /* Primary Interface Files */
  13. #include "Types.h"
  14. /* #include "Resources.h" */
  15. #include "Quickdraw.h"
  16. #include "Windows.h"
  17. /* #include "OSUtils.h" */
  18.  
  19. /* Commonly Included files */
  20. /* #include "ToolUtils.h" */
  21. /* #include "TextEdit.h" */
  22. /* #include "Controls.h" */
  23.  
  24. /* Other Interface files */
  25. /* #include "AppleTalk.h" */
  26. /* #include "CursorCtl.h" */
  27. /* #include "Desk.h" */
  28. /* #include "DeskBus.h" */
  29. /* #include "Devices.h" */
  30. /* #include "Dialogs.h" */
  31. /* #include "DiskInit.h" */
  32. /* #include "Disks.h" */
  33. /* #include "ErrMgr.h" */
  34. #include "Errors.h"
  35. /* #include "Events.h" */
  36. #include "Files.h"
  37. /* #include "Fonts.h" */
  38. /* #include "Graf3D.h" */
  39. /* #include "Lists.h" */
  40. #include "Memory.h"
  41. /* #include "Menus.h" */
  42. #include "Packages.h"
  43. /* #include "Palette.h" */
  44. /* #include "Perf.h" */
  45. /* #include "Picker.h" */
  46. /* #include "Printing.h" */
  47. /* #include "Retrace.h" */
  48. /* #include "ROMDefs.h" */
  49. /* #include "SANE.h" */
  50. #include "Scrap.h"
  51. /* #include "Script.h" */
  52. /* #include "SCSI.h" */
  53. /* #include "SegLoad.h" */
  54. /* #include "Serial.h" */
  55. /* #include "Slots.h" */
  56. /* #include "Sound.h" */
  57. /* #include "Start.h" */
  58. /* #include "Strings.h" */
  59. /* #include "Time.h" */
  60. /* #include "Traps.h" */
  61. /* #include "Values.h" */
  62. /* #include "VarArgs.h" */
  63. /* #include "Video.h" */
  64.  
  65. /* Application-specific Include files */
  66. #include "::TiffLibrary:TIFFLib.h"
  67. #include "sample.h"
  68. #include "messages.h"
  69.  
  70. static Ptr    SetIDPtr();
  71. static void    CleanUp();
  72. static void    InitID();
  73.  
  74. #define    MAXIMAGESIZE    0x8000        /* Limit images to 32K for now */
  75. #define    INFINITY        0x4000000    /* TIFF Spec says 2**32-1 but this is big enough */
  76.  
  77. /*
  78.  * Read in an image from a TIFF format file.  As the code demonstrates, we
  79.  * do not read in very complicated images.  We read in a number of tags,
  80.  * and reject the image as an unsuitable tiff file if any of several
  81.  * conditions exist.  We do not read in images that have more than one bit
  82.  * of image data per pixel.  We do not scale images.  Of those simple images
  83.  * that we do read, we will only read the first 32k of that image.
  84.  */
  85. Boolean ReadTiff(refNum, myBitMapPtr)
  86. Int16 refNum;
  87. BitMap *myBitMapPtr;
  88. {
  89.     Handle            listH;
  90.     Boolean            oddRowBytes;
  91.     Int8            dummy;
  92.     Int16            byteOrder,
  93.                     rowBytes,
  94.                     scrnHRes,
  95.                     scrnVRes;
  96.     Int32            tagOffset,
  97.                     nextDirOffset,
  98.                     nextFileFree,    /* next free location in output file */
  99.                     dirOffset,
  100.                     rowsPerImage,
  101.                     count,
  102.                     size;
  103.     Rational        xRes,
  104.                     yRes;
  105.     Rect            imageRect;
  106.     TiffDirEntry    tagDirEntry;
  107.     id                id;                /* image description */
  108.  
  109.     InitID(&id);    
  110.     ScreenRes(&scrnHRes, &scrnVRes);    /* if needed for defaults */
  111.     
  112.     /*
  113.      * Read in header and Tags
  114.      */
  115.  
  116.     if (TReadHeader(refNum, &dirOffset, &byteOrder) != noErr) {
  117.         ErrorMessage(BADREADHEADER);
  118.         return(false);
  119.     }
  120.  
  121.     if(TReadTags(refNum, byteOrder,
  122.                 &listH, dirOffset, &nextDirOffset) != noErr) {
  123.         ErrorMessage(BADREADTAGS);
  124.         return(false);
  125.     }
  126.     
  127.     /*
  128.      * Get tags values.
  129.      */
  130.     /* SUBFILE_TYPE_TAG */
  131.     if (TFindTag(listH, &tagOffset, SUBFILE_TYPE_TAG))
  132.         TGetTag(listH, tagOffset, &id.subfileType, sizeof(id.subfileType));
  133.     else {
  134.         ErrorMessage(BADTIFF);
  135.         CleanUp(listH, &id);
  136.         return(false);
  137.     }
  138.     /* IMAGE_WIDTH_TAG */
  139.     if (TFindTag(listH, &tagOffset, IMAGE_WIDTH_TAG))
  140.         TGetTag(listH, tagOffset, &id.imageWidth, sizeof(id.imageWidth));
  141.     else {
  142.         ErrorMessage(BADTIFF);
  143.         CleanUp(listH, &id);
  144.         return(false);
  145.     }
  146.     /* IMAGE_LENGTH_TAG */
  147.     if (TFindTag(listH, &tagOffset, IMAGE_LENGTH_TAG))
  148.         TGetTag(listH, tagOffset, &id.imageLength, sizeof(id.imageLength));
  149.     else {
  150.         ErrorMessage(BADTIFF);
  151.         CleanUp(listH, &id);
  152.         return(false);
  153.     }
  154.     /* ROWS_PER_STRIP_TAG */
  155.     if (TFindTag(listH, &tagOffset, ROWS_PER_STRIP_TAG)) {
  156.         TGetTag(listH, tagOffset, &id.rowsPerStrip, sizeof(id.rowsPerStrip));
  157.         tagDirEntry = GetDirEntry(listH, tagOffset);
  158.         switch(tagDirEntry.type) {
  159.         case LONG:
  160.             break;
  161.         case SHORT:    /* ok, but convert returned value */
  162.             id.rowsPerStrip = (long)( *((Int16 *)(&id.rowsPerStrip)) );
  163.             break;
  164.         default:
  165.             ErrorMessage(BADTIFF);
  166.             CleanUp(listH, &id);
  167.             return(false);
  168.         }
  169.     }
  170.     else {
  171.         id.rowsPerStrip = INFINITY;
  172.     }
  173.     /* SAMPLES_PER_PIXEL_TAG */
  174.     if (TFindTag(listH, &tagOffset, SAMPLES_PER_PIXEL_TAG))
  175.         TGetTag(listH, tagOffset, &id.samplesPerPixel, sizeof(id.samplesPerPixel));
  176.     else {
  177.         id.samplesPerPixel = 1;
  178.     }
  179.     /* BITS_PER_SAMPLE_TAG */
  180.     id.bitsPerSample = SetIDPtr(listH, BITS_PER_SAMPLE_TAG, 1L, SHORT);
  181.     if (id.bitsPerSample == nil) {
  182.             CleanUp(listH, &id);
  183.             return(false);
  184.     }
  185.     /* PLANAR_CONFIG_TAG */
  186.     if (TFindTag(listH, &tagOffset, PLANAR_CONFIG_TAG))
  187.         TGetTag(listH, tagOffset, &id.planarConfig, sizeof(id.planarConfig));
  188.     else
  189.         id.planarConfig = 1;
  190.     /* COMPRESSION_TAG */
  191.     id.compression = SetIDPtr(listH, COMPRESSION_TAG, 1L, SHORT);
  192.     if (id.compression == nil) {
  193.             CleanUp(listH, &id);
  194.             return(false);
  195.     }
  196.     /* MIN_SAMPLE_VALUE_TAG */
  197.     id.minSampleValue = SetIDPtr(listH, MIN_SAMPLE_VALUE_TAG, 0L, SHORT);
  198.     if (id.minSampleValue == nil) {
  199.             CleanUp(listH, &id);
  200.             return(false);
  201.     }
  202.     /* MAX_SAMPLE_VALUE_TAG */
  203.     id.maxSampleValue = SetIDPtr(listH, MAX_SAMPLE_VALUE_TAG,
  204.                             (Int32)((1 << *id.bitsPerSample) - 1), SHORT);
  205.     if (id.maxSampleValue == nil) {
  206.             CleanUp(listH, &id);
  207.             return(false);
  208.     }
  209.     /* PHOTOMETRIC_INTERP_TAG */
  210.     if (TFindTag(listH, &tagOffset, PHOTOMETRIC_INTERP_TAG))
  211.         TGetTag(listH, tagOffset, &id.photoInterp, sizeof(id.photoInterp));
  212.     else {
  213.         id.photoInterp = 0;    /* assume mac photometric interpretation */
  214.     }
  215.     /* FILL_ORDER_TAG */
  216.     if (TFindTag(listH, &tagOffset, FILL_ORDER_TAG))
  217.         TGetTag(listH, tagOffset, &id.fillOrder, sizeof(id.fillOrder));
  218.     else
  219.         id.fillOrder = 1;
  220.     /* ORIENTATION_TAG */
  221.     if (TFindTag(listH, &tagOffset, ORIENTATION_TAG))
  222.         TGetTag(listH, tagOffset, &id.orientation, sizeof(id.orientation));
  223.     else
  224.         id.orientation = 1;
  225.     /* X_RESOLUTION_TAG */
  226.     if (TFindTag(listH, &tagOffset, X_RESOLUTION_TAG))
  227.         TGetTag(listH, tagOffset, &id.xResolution, sizeof(id.xResolution));
  228.     else {
  229.         id.xResolution.numerator = (Int32)scrnHRes;
  230.         id.xResolution.denominator = 1;
  231.     }
  232.     /* Y_RESOLUTION_TAG */
  233.     if (TFindTag(listH, &tagOffset, Y_RESOLUTION_TAG))
  234.         TGetTag(listH, tagOffset, &id.yResolution, sizeof(id.yResolution));
  235.     else {
  236.         id.yResolution.numerator = (Int32)scrnVRes;
  237.         id.yResolution.denominator = 1;
  238.     }
  239.     
  240.     /*
  241.      * Initialize of non-tag values.
  242.      */
  243.     oddRowBytes = (((id.imageWidth * (*id.bitsPerSample)) + 7) / 8) % 2 != 0;
  244.     id.stripsPerImage =
  245.                     (id.imageLength + id.rowsPerStrip - 1) / id.rowsPerStrip;
  246.  
  247.     /*
  248.      *    Check Tag Values to see if we can read this TIFF file.
  249.      *    
  250.      *    NOTE: Although the majority of the tag were read, all the values
  251.      *    obtained are not used in displaying the image in THIS PROGRAM.
  252.      *    Those not used were read in simply for to provide the example.
  253.      */
  254.     DBG(DisplayID(&id));     
  255.     DBG(DebugMessage("image row bytes %ld",
  256.         ((id.imageWidth * (*id.bitsPerSample + 7)) / 8)));
  257.     DBG(DebugMessage("oddRowBytes=%s", oddRowBytes ? "true" : "false"));
  258.     if ( (id.samplesPerPixel != 1)                        ||
  259.          (*id.bitsPerSample != 1)                        ||
  260.          (id.planarConfig != 1 && id.planarConfig != 2) )    {
  261.         ErrorMessage(BADTIFF);
  262.         CleanUp(listH, &id);
  263.         return(false);
  264.     }
  265.     if (id.photoInterp != 0)    /* We don't translate yet so let 'em know */
  266.         ErrorMessage(BADPHOTOINTERP);
  267.         
  268.     rowBytes = (((id.imageWidth - 1) / (2 * 8)) + 1) * 2;
  269.     /* only make image as much as will fit in MAXIMAGESIZE for now */
  270.     size = id.imageLength * rowBytes;
  271.     if (size > MAXIMAGESIZE) {
  272.         ErrorMessage(IMAGECROPWARN);
  273.         size = MAXIMAGESIZE;
  274.     }
  275.     rowsPerImage = size / rowBytes;
  276.  
  277.     /*
  278.      * Prepare bitmap.
  279.      */
  280.     if (myBitMapPtr->baseAddr != nil)
  281.         DisposPtr(myBitMapPtr->baseAddr);
  282.     if ((myBitMapPtr->baseAddr = MyNewPtr(size)) == nil) {
  283.         CleanUp(listH, &id);
  284.         return(false);
  285.     }
  286.     myBitMapPtr->rowBytes = rowBytes;
  287.     myBitMapPtr->bounds.top = 0;
  288.     myBitMapPtr->bounds.left = 0;
  289.     myBitMapPtr->bounds.bottom = rowsPerImage;
  290.     myBitMapPtr->bounds.right = id.imageWidth;
  291.  
  292.      
  293.     /*
  294.      * Read in image.
  295.      */
  296.     DBG(DebugMessage("rowsPerImage=%ld",rowsPerImage));
  297.     if (TReadImage(refNum, listH,
  298.                     0L, myBitMapPtr->baseAddr, rowsPerImage, -1) != noErr) {
  299.         CleanUp(listH, &id);                        
  300.         return(false);
  301.     }
  302.     if (oddRowBytes)
  303.         TFixOddRowBytes(myBitMapPtr);
  304.     DisplayImage(FrontWindow(), myBitMapPtr);
  305.  
  306.     CleanUp(listH, &id);                        
  307.     return(true);
  308. }
  309.  
  310. void WriteTiff(refNum, myBitMapPtr)
  311. Int16 refNum;
  312. BitMap *myBitMapPtr;
  313. {
  314.     Handle        listH;
  315.     Ptr            bufferPtr;
  316.     Boolean        oddRowBytes;
  317.     Int8        dummy;
  318.     Int16        byteOrder,
  319.                 subfileType,
  320.                 imageWidth,
  321.                 imageLength,
  322.                 fillOrder,
  323.                 compressType,
  324.                 photoInterp,
  325.                 bitsPerPixel,
  326.                 minSampleValue,
  327.                 maxSampleValue,
  328.                 orientation,
  329.                 tiffRowBytes,    /* number of bytes per row in TIFF format */
  330.                 plane,            /* dummy parameter for TWriteImageStrip */
  331.                 scrnHRes,
  332.                 scrnVRes;
  333.     Int32        rowsPerStrip,
  334.                 nextFileFree,    /* next free location in output file */
  335.                 startLine,
  336.                 numLines,
  337.                 dirOffset,
  338.                 count;
  339.     Rational    xRes,
  340.                 yRes;
  341.     Rect        imageRect;
  342.     
  343.     /* get a handle for the in memory tag list */
  344.     listH = NewHandle(0);
  345.     if (MemError() != noErr) {
  346.         ErrorMessage(BADMEMORY);
  347.         return;
  348.     }
  349.  
  350.     ScreenRes(&scrnHRes, &scrnVRes);
  351.     imageRect = myBitMapPtr->bounds;
  352.     /* write out 8 rows per strip - 8 is an arbitrary number */
  353.     rowsPerStrip = MIN(imageRect.bottom - imageRect.top, 8);
  354.  
  355.     /* initialize tag values */
  356.     byteOrder = MOTOROLA;
  357.     subfileType = 1;
  358.     imageWidth = imageRect.right;
  359.     imageLength = imageRect.bottom;
  360.     bitsPerPixel = 1;
  361.     fillOrder = 1;
  362.     compressType = 1;
  363.     photoInterp = 0;
  364.     minSampleValue = 0;
  365.     maxSampleValue = (1 << bitsPerPixel) - 1;
  366.     orientation = 1;
  367.     xRes.numerator = (Int32)scrnHRes;
  368.     xRes.denominator = 1;
  369.     yRes.numerator = (Int32)scrnVRes;
  370.     yRes.denominator = 1;
  371.      
  372.     tiffRowBytes = (imageRect.right * bitsPerPixel + 7) / 8;
  373.     oddRowBytes = (tiffRowBytes % 2) != 0;
  374.     DBG(DebugMessage("tiffRowBytes=%d oddRowBytes=%s",
  375.         tiffRowBytes, oddRowBytes == false ? "false" : "true"));
  376.  
  377.     /*
  378.      * Put tags in memory list.
  379.      * The order tags are put in the list with TPutPtrTag is NOT important.
  380.      */
  381.     if (    TPutPtrTag(listH, SUBFILE_TYPE_TAG, SHORT,
  382.                                     1L,    &subfileType)    != noErr    ||
  383.             TPutPtrTag(listH, IMAGE_WIDTH_TAG,    SHORT,
  384.                                     1L, &imageWidth)     != noErr    ||
  385.             TPutPtrTag(listH, IMAGE_LENGTH_TAG, SHORT,
  386.                                     1L, &imageLength)    != noErr    ||
  387.             TPutPtrTag(listH, ROWS_PER_STRIP_TAG, LONG,
  388.                                     1L, &rowsPerStrip)    != noErr    ||
  389.             TPutPtrTag(listH, X_RESOLUTION_TAG, RATIONAL,
  390.                                     1L, &xRes)            != noErr    ||
  391.             TPutPtrTag(listH, Y_RESOLUTION_TAG, RATIONAL,
  392.                                     1L, &yRes)            != noErr    ||
  393.             TPutPtrTag(listH, BITS_PER_SAMPLE_TAG, SHORT,
  394.                                     1L,&bitsPerPixel)    != noErr    ||
  395.             TPutPtrTag(listH, COMPRESSION_TAG, SHORT,
  396.                                     1L, &compressType)    != noErr    ||
  397.             TPutPtrTag(listH, FILL_ORDER_TAG, SHORT,
  398.                                     1L, &fillOrder)        != noErr    ||
  399.             TPutPtrTag(listH, ORIENTATION_TAG, SHORT,
  400.                                     1L, &orientation)    != noErr    ||
  401.             TPutPtrTag(listH, PHOTOMETRIC_INTERP_TAG, SHORT,
  402.                                     1L, &photoInterp)    != noErr    ) {
  403.         ErrorMessage(BADPUTTAGS);
  404.         return;
  405.     }
  406.     
  407.     /* leave room for header in output file */
  408.     SetEOF(refNum, (Int32)sizeof(TiffHeader));
  409.     nextFileFree = sizeof(TiffHeader);
  410.     
  411.     /*
  412.      * Write out image to file, fixing from Macintosh rounding of rows to the
  413.      * nearest 2 bytes, to the TIFF rounding of rows to the nearest byte.
  414.      */
  415.     if (oddRowBytes)
  416.         TUnfixOddRowBytes(myBitMapPtr);        /* round rows to nearest byte */
  417.  
  418.     startLine = 0;
  419.     bufferPtr = myBitMapPtr->baseAddr;
  420.     while  (startLine < imageLength) {
  421.         numLines = MIN(imageLength - startLine, rowsPerStrip);
  422.         if (TWriteImageStrip(refNum, &nextFileFree, listH,
  423.                         startLine, numLines, bufferPtr, plane) != noErr) {
  424.             ErrorMessage(BADWRITEIMAGE);
  425.             return;
  426.         }
  427.         startLine += numLines;
  428.         bufferPtr += numLines * tiffRowBytes;
  429.     }
  430.     
  431.     if (oddRowBytes)
  432.         TFixOddRowBytes(myBitMapPtr);        /* round rows to nearest word */
  433.  
  434.     /* directory must be on word boundary */
  435.     if (nextFileFree % 2 != 0) {
  436.         /* add filler byte */
  437.         count = 1;
  438.         if (FSWrite(refNum, &count, &dummy) != noErr) {
  439.             ErrorMessage(BADWRITE);
  440.             return;
  441.         }
  442.         nextFileFree++;
  443.     }
  444.  
  445.     dirOffset = nextFileFree;
  446.     
  447.     if (TWriteTags(refNum, byteOrder, &nextFileFree, listH, 0L) != noErr) {
  448.         ErrorMessage(BADWRITETAGS);
  449.         return;
  450.     }
  451.     if (TWriteHeader(refNum, dirOffset, byteOrder) != noErr) {
  452.         ErrorMessage(BADWRITEHEADER);
  453.     }
  454. }
  455.  
  456. /*
  457.  * Free the list handle and any memory allocated to image description structure.
  458.  */
  459. static void CleanUp(listHandle, idPtr)
  460. Handle listHandle;
  461. id *idPtr;
  462. {
  463.     MyDisposPtr(&idPtr->bitsPerSample);
  464.     MyDisposPtr(&idPtr->compression);
  465.     MyDisposPtr(&idPtr->docName);
  466.     MyDisposPtr(&idPtr->imageDescription);
  467.     MyDisposPtr(&idPtr->make);
  468.     MyDisposPtr(&idPtr->model);
  469.     MyDisposPtr(&idPtr->stripOffsets);
  470.     MyDisposPtr(&idPtr->stripByteCounts);
  471.     MyDisposPtr(&idPtr->minSampleValue);
  472.     MyDisposPtr(&idPtr->maxSampleValue);
  473.     MyDisposPtr(&idPtr->pageName);
  474.     MyDisposPtr(&idPtr->freeOffsets);
  475.     MyDisposPtr(&idPtr->freeByteCounts);
  476.     MyDisposPtr(&idPtr->grayResponseCurve);
  477.     MyDisposPtr(&idPtr->colorResponseCurves);
  478.     DisposHandle(listHandle);
  479. }
  480.  
  481. void InitID(idPtr)
  482. id *idPtr;
  483. {
  484.     idPtr->subfileType = -1;
  485.     idPtr->imageWidth = 0;
  486.     idPtr->imageLength = 0;
  487.     idPtr->bitsPerSample = nil;
  488.     idPtr->compression = nil;
  489.     idPtr->photoInterp = -1;
  490.     idPtr->threshholding = -1;
  491.     idPtr->cellWidth = -1;
  492.     idPtr->cellLength = -1;
  493.     idPtr->fillOrder = 0;
  494.     idPtr->docName = nil;
  495.     idPtr->imageDescription = nil;
  496.     idPtr->make = nil;
  497.     idPtr->model = nil;
  498.     idPtr->stripOffsets = nil;
  499.     idPtr->orientation = -1;
  500.     idPtr->samplesPerPixel = 0;
  501.     idPtr->rowsPerStrip = 0;
  502.     idPtr->stripsPerImage = 0;
  503.     idPtr->stripByteCounts = nil;
  504.     idPtr->minSampleValue = nil;
  505.     idPtr->maxSampleValue = nil;
  506.     idPtr->xResolution.numerator = 0;
  507.     idPtr->xResolution.denominator = 0;
  508.     idPtr->yResolution.numerator = 0;
  509.     idPtr->yResolution.denominator = 0;
  510.     idPtr->planarConfig = -1;
  511.     idPtr->pageName = nil;
  512.     idPtr->xPosition.numerator = 0;
  513.     idPtr->xPosition.denominator = 0;
  514.     idPtr->yPosition.numerator = 0;
  515.     idPtr->yPosition.denominator = 0;
  516.     idPtr->freeOffsets = nil;
  517.     idPtr->freeByteCounts = nil;
  518.     idPtr->grayResponseUnit = -1;
  519.     idPtr->grayResponseCurve = nil;
  520.     idPtr->group3Options = 0;
  521.     idPtr->group4Options = 0;
  522.     idPtr->resolutionUnit = -1;
  523.     idPtr->pageNumber[0] = 0;
  524.     idPtr->pageNumber[1] = 0;
  525.     idPtr->colorResponseUnit = -1;
  526.     idPtr->colorResponseCurves = nil;
  527. }
  528.  
  529. TiffDirEntry GetDirEntry(listHandle, tagOffset)
  530. Handle    listHandle;
  531. Int32    tagOffset;
  532. {
  533.     Ptr                p;
  534.     
  535.     
  536.     /* get pointer to tag list */
  537.     p = &(**listHandle);    /* HANDLE DEREFERENCE */
  538.     /* get pointer to our tag's directory entry */
  539.     p += tagOffset;
  540.     /* return the whole Directory Entry Structure, not a pointer to it */
  541.     return(*((TiffDirEntry *)p));
  542. }
  543.  
  544.  
  545. Int16 TypeSize(type)
  546. Int16 type;
  547. {
  548.     switch (type) {
  549.         case BYTE:
  550.             return(BYTESIZE);
  551.         case ASCII:
  552.             return(ASCIISIZE);
  553.         case SHORT:
  554.             return(SHORTSIZE);
  555.         case LONG:
  556.             return(LONGSIZE);
  557.         case RATSIZE:
  558.             return(RATSIZE);
  559.     }
  560. }
  561.  
  562. Ptr SetIDPtr(listHandle, tag, defaultValue, defaultType)
  563. Handle listHandle;
  564. Int16 tag;
  565. Int32 defaultValue;        /* won't handle defaults larger than 4 bytes */
  566. Int32 defaultType;
  567. {
  568.     TiffDirEntry    tagDE;
  569.     Ptr                p;
  570.     Int32            tagOffset,
  571.                     size,
  572.                     nvals;
  573.     
  574.     if (TFindTag(listHandle, &tagOffset, tag)) {
  575.         tagDE = GetDirEntry(listHandle, tagOffset);
  576.         size = TypeSize(tagDE.type) * tagDE.length;
  577.         if ((p = MyNewPtr(size)) != nil)
  578.             TGetTag(listHandle, tagOffset, p, size);
  579.     }
  580.     else if (defaultType != 0) {
  581.         if ((p = MyNewPtr(defaultType)) != nil) {
  582.             switch (defaultType) {
  583.                 case BYTE:
  584.                     *(unsigned char *)p = defaultValue;
  585.                     break;
  586.                 case ASCII:
  587.                     *(unsigned char *)p = defaultValue;
  588.                     break;
  589.                 case SHORT:
  590.                     *(unsigned short *)p = defaultValue;
  591.                     break;
  592.                 case LONG:
  593.                     *(unsigned long *)p = defaultValue;
  594.                     break;
  595.                 case RATIONAL:
  596.                     ((Rational *)p)->numerator = defaultValue;
  597.                     ((Rational *)p)->denominator = 1;
  598.                     break;
  599.             }
  600.         }
  601.     }
  602.     else
  603.         p = nil;
  604.     return(p);
  605. }
  606.  
  607. #ifdef DEBUG
  608. DisplayID(idPtr)
  609. id *idPtr;
  610. {
  611.     DebugMessage("subfileType=%ld imageWidth=%ld imageLength=%ld bitsPerSample=%ld",
  612.                 idPtr->subfileType,
  613.                 idPtr->imageWidth,
  614.                 idPtr->imageLength,
  615.                 idPtr->bitsPerSample != nil ? *idPtr->bitsPerSample : -1);
  616.     
  617.     DebugMessage("compression=%ld photoInterp=%ld threshholding=%ld cellWidth=%ld cellLength=%ld",
  618.                 idPtr->compression != nil ? *idPtr->compression : -1,
  619.                 idPtr->photoInterp,
  620.                 idPtr->threshholding,
  621.                 idPtr->cellWidth,
  622.                 idPtr->cellLength);
  623.  
  624.     DebugMessage("fillOrder=%ld docName=%s imageDescription=%s make=%s model=%s",
  625.                 idPtr->fillOrder,
  626.                 idPtr->docName,
  627.                 idPtr->imageDescription,
  628.                 idPtr->make,
  629.                 idPtr->model);
  630.     
  631.     /* idPtr->stripOffsets = nil; */
  632.     
  633.     DebugMessage("orientation=%ld samplesPerPixel=%ld rowsPerStrip=%ld stripsPerImage=%ld",
  634.                 idPtr->orientation,
  635.                 idPtr->samplesPerPixel,
  636.                 idPtr->rowsPerStrip != INFINITY ? idPtr->rowsPerStrip : -1,
  637.                 idPtr->stripsPerImage);
  638.     
  639.     /* idPtr->stripByteCounts = nil; */
  640.     
  641.     DebugMessage("minSampleValue=%ld maxSampleValue=%ld",
  642.                 idPtr->minSampleValue ? *idPtr->minSampleValue : -1,
  643.                 idPtr->maxSampleValue ? *idPtr->maxSampleValue : -1);
  644.     
  645.     DebugMessage("xRes=%ld/%ld yRes=%ld/%ld planarConfig=%ld",
  646.                 idPtr->xResolution.numerator,
  647.                 idPtr->xResolution.denominator,
  648.                 idPtr->yResolution.numerator,
  649.                 idPtr->yResolution.denominator,
  650.                 idPtr->planarConfig);
  651.     /*            
  652.     idPtr->pageName = nil;
  653.     idPtr->xPosition.numerator = 0;
  654.     idPtr->xPosition.denominator = 0;
  655.     idPtr->yPosition.numerator = 0;
  656.     idPtr->yPosition.denominator = 0;
  657.     idPtr->freeOffsets = nil;
  658.     idPtr->freeByteCounts = nil;
  659.     idPtr->grayResponseUnit = -1;
  660.     idPtr->grayResponseCurve = nil;
  661.     idPtr->group3Options = 0;
  662.     idPtr->group4Options = 0;
  663.     idPtr->resolutionUnit = -1;
  664.     idPtr->pageNumber[0] = 0;
  665.     idPtr->pageNumber[1] = 0;
  666.     idPtr->colorResponseUnit = -1;
  667.     idPtr->colorResponseCurves = nil;
  668.     */
  669. }
  670. #endif